#coding:utf-8
import socket
import socketserver
import threading
import json

class NetStream:
    def __init__(self):
        self.buffer = ""
        self.braceCount = 0
        self.squareBraceCount = 0
        self.quota = False
        self.slash = False

    def StateDone(self):
        return self.braceCount==0 and self.squareBraceCount==0 and not self.quota and not self.slash

    def FixError(self):
        if self.braceCount < 0 or self.squareBraceCount < 0:
            self.braceCount = 0
            self.sqareBraceCount = 0
            self.buffer = ""
            return True
        return False

    def Push(self, streamStr):
        retStr = ""
        splitIndex = 0
        for index in range(len(streamStr)):
            currChar = streamStr[index]
            if self.StateDone():
                if currChar=='{':
                    self.braceCount+=1
                else: splitIndex = index+1
            else:
                if currChar=='\\': self.slash=True
                else:
                    self.slash=False
                    if currChar=='{' and not self.quota: self.braceCount+=1
                    elif currChar=='}' and not self.quota: self.braceCount-=1
                    elif currChar=='[' and not self.quota: self.squareBraceCount+=1
                    elif currChar==']' and not self.quota: self.squareBraceCount-=1
                    elif currChar=='\\': self.slash=True
                    elif currChar=='"' and not self.slash:
                        self.quota = not self.quota
                if self.FixError():
                    splitIndex = index+1
                elif self.StateDone():
                    if not(index==0 and len(self.buffer)==0):
                        self.buffer += streamStr[splitIndex:index+1]
                        splitIndex = index+1
                        retStr = self.buffer
                        self.buffer = ""
        self.buffer += streamStr[splitIndex:]
        return retStr

class DataStorage:
    def __init__(self):
        self.storageMap = {}
        self.lock = threading.Lock()

    def Set(self, key, value):
        self.lock.acquire()
        try:
            if value==None: self.storageMap.pop(key)
            else: self.storageMap[key] = value
        finally:
            self.lock.release()

    def Get(self, key):
        self.lock.acquire()
        try:
            if not self.storageMap.has_key(): return None
            return self.storageMap[key]
        finally:
            self.lock.release()

class SocketProcessor(socketserver.BaseRequestHandler):
    def __init__(self, request, client_address, server):
        self.stream = NetStream()
        self.data = DataStorage()
        return super().__init__(request, client_address, server)

    def handle(self):
        while True:
            data = self.request.recv(1024)
            if len(data)==0: break
            requestStr = self.stream.Push(data.decode())
            request = {}
            try:
                request = json.loads(requestStr)
                for key in request:
                    print("{}:{}".format(key, request[key]))
                    if key.find("ps:")==0:
                        command = key[3:]
                        if command == "set":
                            savedKeySet = []
                            for itemKey in request[key]:
                                self.data.Set(itemKey, json.dumps(request[key][itemKey]).encode())
                                savedKeySet.append(itemKey)
                            sendContent = '{"ps:saved":[{'
                            for item in savedKeySet:
                                sendContent += '"'
                                sendContent += item
                                sendContent += '", '
                            sendContent = sendContent[:-2]
                            sendContent += ']}'
                            self.request.sendall(sendContent.encode())
                        elif command == "get":
                            sendContent = self.data.Get(key)
                            self.request.sendall(sendContent.encode())
            except json.decoder.JSONDecodeError:
                pass
        print("connection closed")

class ThisTCPServer(socketserver.ThreadingTCPServer):
    def __init__(self, server_address, RequestHandlerClass, bind_and_activate = True):
        allow_reuse_address = True
        return super().__init__(server_address, RequestHandlerClass, bind_and_activate)

#netStream = NetStream()
#testStr = ["{test:", "}","ntsdf{\"}\"","[]}"]
#for str in testStr:
#    print("test push:{}".format(netStream.Push(str)))


server = ThisTCPServer(('0.0.0.0', 224), SocketProcessor)
try:
    server.serve_forever()
except KeyboardInterrupt:
    server.shutdown()
    server.server_close()